# 序列化模型类
from rest_framework import serializers
from django.contrib.auth.hashers import make_password
from rest_framework.validators import UniqueValidator
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
# 从项目的工具类中导入验证邮箱和手机号码的方法
from mes_api.utils.validators import EmailValidator,MobileValidator,IDValidator,PasswordValidator,IDCardValidator,NameValidator
from django.contrib.auth.models import Group, Permission
from users.models import User, Dept
import re

# 序列化部门类
class DeptSerializer(serializers.ModelSerializer):
    # 状态显示转化
    status_display = serializers.CharField(
        source='get_status_display', required=False)
    class Meta:
        model = Dept
        fields = '__all__'

# 序列化用户组类
class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = '__all__'

# 序列化权限类
class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = '__all__'


# 序列化用户类
class UserSerializer(serializers.ModelSerializer):
    # 状态显示转化
    status_display = serializers.CharField(
        source='get_status_display', required=False)
    # 部门序列化外键显示
    dept = serializers.PrimaryKeyRelatedField(
        required=True, queryset=Dept.objects.all())
    # 序列化外键关联显示部门名称
    dept_name = serializers.StringRelatedField(
        source='dept', read_only=True)
    # 部门序列化名称显示
    dept_name = serializers.CharField(source="dept", read_only=True)
    # 序列化显示姓名并正则验证
    username = serializers.CharField( validators=[NameValidator()])
    # 序列化显示邮箱并正则验证邮箱和判断是否唯一
    email = serializers.EmailField(validators=[EmailValidator(), UniqueValidator(queryset=User.objects.all())])
    # 序列化显示手机号码并正则验证邮箱和判断是否唯一
    mobile = serializers.CharField(validators=[MobileValidator(), UniqueValidator(queryset=User.objects.all())])
    # 序列化显示工号并正则验证工号和判断是否唯一
    id = serializers.CharField(required=True, validators=[IDValidator(), UniqueValidator(queryset=User.objects.all())])
    # 序列化显示身份证号码并正则验证工号和判断是否唯一
    id_card = serializers.CharField(validators=[IDCardValidator(), UniqueValidator(queryset=User.objects.all())])
    # 序列化外键显示用户组
    groups = serializers.PrimaryKeyRelatedField(
        many=True, required=False, queryset=Group.objects.all())
    # 序列化外键关联显示用户组名称
    group_names = serializers.StringRelatedField(
        source='groups', many=True, read_only=True)
    # 序列化显示最后登录时间，创建时间，修改时间
    last_login = serializers.DateTimeField(label='最后登录时间', read_only=True)
    update_time = serializers.DateTimeField(label='最后修改时间', read_only=True)
    create_time = serializers.DateTimeField(label='创建时间', read_only=True)


    class Meta:
        model = User
        fields = '__all__'


    # 验证用户状态
    def validate_status(self, value):
        if value not in [0, 1, 2]:
            raise serializers.ValidationError('用户状态必须为0或1')
        return value

    # 对数据进行验证
    def validate(self, attrs):
        # 如果有密码时对密码进行验证
        if 'password' in attrs:
            # 检查密码和确认密码是否一致
            if attrs['password'] != attrs['password_confirm']:
                raise serializers.ValidationError('两次密码不一致')
            # 删除确认密码字段
            del attrs['password_confirm']
            # 使用密码验证器对密码正则验证
            PasswordValidator().validate(attrs['password'])
            # 对密码进行加密处理
            attrs['password'] = make_password(attrs['password'])
        # 有用户协议时检查用户协议
        if 'user_agreement' in attrs:
            if not attrs['user_agreement']:
                raise serializers.ValidationError('请同意用户协议')
            del attrs['user_agreement']
        # 返回处理后的数据
        return attrs    

# 重写TokenObtainPairSerializer方法
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 重写validate方法
    def validate(self, attrs):
        # 调用父类的validate方法
        data = super().validate(attrs)
        if self.user.status == 0:
            raise serializers.ValidationError("用户待激活")
        if self.user.status == 2:
            raise serializers.ValidationError("用户已冻结")
        data['id'] = self.user.id
        return data
